package com.zh.service.impl;

import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zh.common.ErrorCode;
import com.zh.constant.PriorityConstant;
import com.zh.constant.ProjectConstant;
import com.zh.constant.TaskConstant;
import com.zh.domain.dto.bug.AddBugRequest;
import com.zh.domain.dto.bug.PageBugDynamicRequest;
import com.zh.domain.dto.bug.PageBugRequest;
import com.zh.domain.dto.bug.UpdateBugRequest;
import com.zh.domain.entity.*;
import com.zh.domain.vo.bug.BugDynamicVo;
import com.zh.domain.vo.bug.BugVo;
import com.zh.domain.vo.task.TaskDynamicVo;
import com.zh.domain.vo.task.TaskVo;
import com.zh.domain.vo.user.UserVO;
import com.zh.exception.ThrowUtils;
import com.zh.job.TaskManager;
import com.zh.service.*;
import com.zh.mapper.BugMapper;
import org.springframework.aop.framework.AopContext;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * @author Administrator
 * @description 针对表【bugs(缺陷表)】的数据库操作Service实现
 * @createDate 2025-02-09 16:24:10
 */
@Service
public class BugServiceImpl extends ServiceImpl<BugMapper, Bug>
        implements BugService {

    @Resource
    private UserService userService;
    @Resource
    private BugDynamicsService bugDynamicsService;
    @Resource
    private BugCommentsService bugCommentsService;
    @Resource
    private MessageService messageService;
    @Resource
    private ProjectService projectService;
    @Resource
    private MilestoneService milestoneService;
    @Resource
    private IterationService iterationService;
    @Resource
    private RequirementsService requirementsService;
    @Resource
    private TaskService taskService;
    @Resource
    private BugMapper bugMapper;

    @Override
    @Transactional
    public Boolean addBug(AddBugRequest addBugRequest) {
        BugService proxy = (BugService) AopContext.currentProxy();
        int loginId = StpUtil.getLoginIdAsInt();
        //1.校验参数
        Integer proId = addBugRequest.getProId();
        Integer mileId = addBugRequest.getMileId();
        Integer iterId = addBugRequest.getIterId();
        Integer reqId = addBugRequest.getReqId();
        Integer taskId = addBugRequest.getTaskId();
        String title = addBugRequest.getTitle();
        String description = addBugRequest.getDescription();
        String remark = addBugRequest.getRemark();
        LocalDateTime startTime = addBugRequest.getStartTime();
        LocalDateTime endTime = addBugRequest.getEndTime();
        Integer priority = addBugRequest.getPriority();
        Integer ownerId = addBugRequest.getOwnerId();
        ThrowUtils.throwIf(null == ownerId, ErrorCode.PARAMS_ERROR, "负责人id不能为空");
        ThrowUtils.throwIf(proId == null, ErrorCode.PARAMS_ERROR, "项目id不能为空");
        ThrowUtils.throwIf(!PriorityConstant.validPriority(priority), ErrorCode.PARAMS_ERROR, "非法的优先级");
        ThrowUtils.throwIf(null == startTime, ErrorCode.PARAMS_ERROR, "起始时间不能为空");
        ThrowUtils.throwIf(null == endTime, ErrorCode.PARAMS_ERROR, "截至时间不能为空");
        ThrowUtils.throwIf(StrUtil.isEmpty(title), ErrorCode.PARAMS_ERROR, "标题不能为空");
        ThrowUtils.throwIf(StrUtil.isEmpty(description), ErrorCode.PARAMS_ERROR, "描述不能为空");
        //2. 生成编号 插入数据
        LambdaQueryWrapper<Bug> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Bug::getProId, proId);
        if (null != mileId) {
            queryWrapper.eq(Bug::getMileId, mileId);
        }
        if (null != iterId) {
            queryWrapper.eq(Bug::getIterId, iterId);
        }
        if (null != reqId) {
            queryWrapper.eq(Bug::getReqId, reqId);
        }
        queryWrapper.eq(Bug::getOwnerId, ownerId);
        Long count = bugMapper.selectCount(queryWrapper);
        StringBuilder code = new StringBuilder();
        code.append("B-");
        code.append("P").append(proId).append("-");
        if (null != mileId) {
            code.append("M").append(mileId).append("-");
        }
        if (null != iterId) {
            code.append("I").append(iterId).append("-");
        }
        if (null != reqId) {
            code.append("R").append(reqId).append("-");
        }
        code.append("O").append(ownerId).append("-");
        code.append(count + 1);
        //3. 赋值
        Bug bug = new Bug();
        bug.setCode(code.toString());
        bug.setTitle(title);
        bug.setDescription(description);
        bug.setRemark(remark);
        bug.setStartTime(startTime);
        bug.setEndTime(endTime);
        bug.setPriority(priority);
        bug.setOwnerId(ownerId);
        bug.setCreateBy(loginId);
        bug.setUpdateBy(loginId);
        bug.setCreateAt(LocalDateTime.now());
        bug.setUpdateAt(LocalDateTime.now());
        bug.setProId(proId);
        bug.setMileId(mileId);
        bug.setIterId(iterId);
        bug.setReqId(reqId);
        bug.setTaskId(taskId);
        bug.setStatus(0);
        bug.setDeleted(0);
        boolean saved = proxy.save(bug);
        //3.发送消息给经办人
        if (saved) {
            proxy.sendMessageAndDynamicWhenAdd(loginId, bug);
        }
        return saved;
    }

    @Transactional
    @Async
    public void sendMessageAndDynamicWhenAdd(Integer operatorId, Bug newBug) {
        Integer createBy = newBug.getCreateBy();
        UserVO creator = userService.getUserVoById(createBy);
        //发送动态
        BugDynamics dynamics = new BugDynamics();
        dynamics.setBugId(newBug.getId());
        String content;
        if (newBug.getOwnerId() != null) {
            UserVO ownerVO = userService.getUserVoById(newBug.getOwnerId());
            content = creator.getName() + "为" + ownerVO.getName() + "分配了缺陷 " + newBug.getTitle() + '.';
        } else {
            content = creator.getName() + "创建了缺陷" + newBug.getTitle() + "-" + newBug.getId() + '.';
        }
        dynamics.setContent(content);
        dynamics.setCreateBy(operatorId);
        dynamics.setUpdateBy(operatorId);
        bugDynamicsService.save(dynamics);
        //发送消息
        Message message = new Message();
        String messageContent = creator.getName() +
                " 为你分配了缺陷 " +
                newBug.getTitle() +
                ",请及时处理.";
        message.setContent(messageContent);
        message.setSendId(creator.getId());
        message.setCreateAt(LocalDateTime.now());
        message.setCreateBy(operatorId);
        message.setUpdateAt(LocalDateTime.now());
        message.setUpdateBy(operatorId);
        message.setNoticeType(0);
        message.setType(4);
        Map<String, Object> paramsToOwner = new HashMap<>();
        paramsToOwner.put("bugId", Optional.ofNullable(newBug.getId()).map(Object::toString).orElse(null));
        paramsToOwner.put("proId", Optional.ofNullable(newBug.getProId()).map(Object::toString).orElse(null));
        paramsToOwner.put("iterId", Optional.ofNullable(newBug.getIterId()).map(Object::toString).orElse(null));
        paramsToOwner.put("milestoneId", Optional.ofNullable(newBug.getMileId()).map(Object::toString).orElse(null));
        paramsToOwner.put("reqId", Optional.ofNullable(newBug.getReqId()).map(Object::toString).orElse(null));
        paramsToOwner.put("taskId", Optional.ofNullable(newBug.getTaskId()).map(Object::toString).orElse(null));
        paramsToOwner.put("payloadType", "bug");
        paramsToOwner.put("title", newBug.getTitle());
        message.setParams(paramsToOwner);
        message.setStatus(1);
        message.setDeleted(0);
        messageService.sendMessage(message, List.of(newBug.getOwnerId()));
    }

    @Override
    public Page<BugVo> pageBugs(PageBugRequest pageBugRequest) {
        //1.参数校验
        Integer proId = pageBugRequest.getProId();
        Integer mileId = pageBugRequest.getMileId();
        Integer iterId = pageBugRequest.getIterId();
        Integer reqId = pageBugRequest.getReqId();
        Integer taskId = pageBugRequest.getTaskId();
        String title = pageBugRequest.getTitle();
        Integer ownerId = pageBugRequest.getOwnerId();
        Integer status = pageBugRequest.getStatus();
        pageBugRequest.standardizeSize();
        Integer current = pageBugRequest.getCurrent();
        Integer pageSize = pageBugRequest.getPageSize();
        Page<Bug> page = new Page<>(current, pageSize);
        LambdaQueryWrapper<Bug> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper
                .eq(proId != null, Bug::getProId, proId)
                .eq(mileId != null, Bug::getMileId, mileId)
                .eq(iterId != null, Bug::getIterId, iterId)
                .eq(reqId != null, Bug::getReqId, reqId)
                .eq(taskId != null, Bug::getTaskId, taskId)
                .likeRight(StrUtil.isNotBlank(title), Bug::getTitle, title)
                .eq(ownerId != null, Bug::getOwnerId, ownerId)
                .eq(ProjectConstant.isValidStatus(status), Bug::getStatus, status)
                .eq(Bug::getDeleted, 0)
                .orderByAsc(Bug::getStatus)
                .orderByDesc(Bug::getCreateAt)
                .orderByDesc(Bug::getCompleteTime);

        Page<Bug> bugPage = bugMapper.selectPage(page, queryWrapper);
        List<Bug> records = bugPage.getRecords();
        List<Integer> userIdList = records.stream()
                .flatMap(bug -> Stream.of(bug.getOwnerId(), bug.getCreateBy()))
                .filter(Objects::nonNull)
                .distinct()
                .collect(Collectors.toList());
        List<UserVO> userVOList = userService.listUserVoByIds(userIdList);
        Map<Integer, UserVO> userVOMap = userVOList.stream().collect(Collectors.toMap(UserVO::getId, userVO -> userVO));
        List<BugVo> TaskVoList = records.stream().map(bug -> {
            BugVo bugVo = BeanUtil.copyProperties(bug, BugVo.class);
            bugVo.setOwner(userVOMap.get(bug.getOwnerId()));
            bugVo.setCreator(userVOMap.get(bug.getCreateBy()));
            bugVo.setUpdater(userVOMap.get(bug.getUpdateBy()));
            return bugVo;
        }).collect(Collectors.toList());

        Page<BugVo> bugVoPage = new Page<>(current, pageSize);
        BeanUtil.copyProperties(bugPage, bugVoPage);
        bugVoPage.setRecords(TaskVoList);
        return bugVoPage;
    }

    @Override
    @Transactional
    public Boolean updateBug(UpdateBugRequest updateBugRequest) {
        int loginId = StpUtil.getLoginIdAsInt();
        BugService proxy = (BugService) AopContext.currentProxy();
        //1.参数校验
        Integer id = updateBugRequest.getId();
        Integer proId = updateBugRequest.getProId();
        Integer mileId = updateBugRequest.getMileId();
        Integer iterId = updateBugRequest.getIterId();
        Integer reqId = updateBugRequest.getReqId();
        Integer taskId = updateBugRequest.getTaskId();
        String title = updateBugRequest.getTitle();
        String description = updateBugRequest.getDescription();
        String remark = updateBugRequest.getRemark();
        Integer ownerId = updateBugRequest.getOwnerId();
        Integer priority = updateBugRequest.getPriority();
        LocalDateTime startTime = updateBugRequest.getStartTime();
        LocalDateTime endTime = updateBugRequest.getEndTime();
        Integer status = updateBugRequest.getStatus();
        ThrowUtils.throwIf(null == id, ErrorCode.PARAMS_ERROR, "缺陷id不能为空");
        synchronized (id.toString()) {
            Bug oldBug = proxy.getById(id);
            Bug updateBug = new Bug();
            LambdaUpdateWrapper<Bug> updateWrapper = new LambdaUpdateWrapper<>();
            updateWrapper.eq(Bug::getId, id)
                    .set(StrUtil.isNotBlank(title), Bug::getTitle, title)
                    .set(StrUtil.isNotBlank(description), Bug::getDescription, description)
                    .set(StrUtil.isNotBlank(remark), Bug::getRemark, remark)
                    .set(null != ownerId, Bug::getOwnerId, ownerId)
                    .set(null != priority, Bug::getPriority, priority)
                    .set(null != startTime, Bug::getStartTime, startTime)
                    .set(null != endTime, Bug::getEndTime, endTime)
                    .set(ProjectConstant.isValidStatus(status), Bug::getStatus, status);
            if (status != null && status == 4) {
                updateBug.setCompleteTime(LocalDateTime.now());
            }
            boolean updated = bugMapper.update(updateBug, updateWrapper) > 0;
            Bug updatedBug = bugMapper.selectById(id);
            if (updated) {
                sendMessageAndDynamicWhenUpdate(loginId, oldBug, updatedBug);
            }
            return updated;
        }
    }

    @Transactional
    @Async
    public void sendMessageAndDynamicWhenUpdate(int operatorId, Bug oldBug, Bug newBug) {
        Integer updateBy = newBug.getUpdateBy();
        UserVO updater = userService.getUserVoById(updateBy);
        BugDynamics templateDynamics = new BugDynamics();
        templateDynamics.setBugId(newBug.getId());
        templateDynamics.setCreateBy(operatorId);
        templateDynamics.setUpdateBy(operatorId);

        List<BugDynamics> bugDynamicsList = new ArrayList<>();
        List<String> contentList = new ArrayList<>();
        generateDynamicContent(oldBug, newBug, contentList, updater);
        contentList.forEach(dynamicContent -> {
            BugDynamics dynamics = BeanUtil.copyProperties(templateDynamics, BugDynamics.class);
            dynamics.setContent(dynamicContent);
            dynamics.setCreateAt(LocalDateTime.now());
            dynamics.setUpdateAt(LocalDateTime.now());
            dynamics.setStatus(1);
            dynamics.setDeleted(0);

            bugDynamicsList.add(dynamics);
        });
        bugDynamicsService.saveBatch(bugDynamicsList);
        // 切换了负责人发送消息
        if (!Objects.equals(oldBug.getOwnerId(), newBug.getOwnerId())) {
            UserVO oldOwner = userService.getUserVoById(oldBug.getOwnerId());
            UserVO newOwner = userService.getUserVoById(newBug.getOwnerId());
            Message messageToOldOwner = new Message();
            //发送给旧负责人
            String messageContent = updater.getName() +
                    " 将你负责的缺陷 " +
                    newBug.getTitle() +
                    "移交给 " +
                    newOwner.getName();
            messageToOldOwner.setContent(messageContent);
            messageToOldOwner.setSendId(updater.getId());
            messageToOldOwner.setCreateAt(LocalDateTime.now());
            messageToOldOwner.setCreateBy(operatorId);
            messageToOldOwner.setUpdateAt(LocalDateTime.now());
            messageToOldOwner.setUpdateBy(operatorId);
            messageToOldOwner.setNoticeType(0);
            messageToOldOwner.setType(4);
            Map<String, Object> paramsToOldOwner = new HashMap<>();
            paramsToOldOwner.put("bugId", Optional.ofNullable(newBug.getId()).map(Object::toString).orElse(null));
            paramsToOldOwner.put("proId", Optional.ofNullable(newBug.getProId()).map(Object::toString).orElse(null));
            paramsToOldOwner.put("iterId", Optional.ofNullable(newBug.getIterId()).map(Object::toString).orElse(null));
            paramsToOldOwner.put("milestoneId", Optional.ofNullable(newBug.getMileId()).map(Object::toString).orElse(null));
            paramsToOldOwner.put("reqId", Optional.ofNullable(newBug.getReqId()).map(Object::toString).orElse(null));
            paramsToOldOwner.put("taskId", Optional.ofNullable(newBug.getTaskId()).map(Object::toString).orElse(null));
            paramsToOldOwner.put("payloadType", "bug");
            paramsToOldOwner.put("title", newBug.getTitle());
            messageToOldOwner.setParams(paramsToOldOwner);
            messageToOldOwner.setStatus(1);
            messageToOldOwner.setDeleted(0);
            messageService.sendMessage(messageToOldOwner, List.of(oldOwner.getId()));
            // 发送给新负责人
            Message messageToNewOwner = new Message();
            String messageContent1 = updater.getName() +
                    " 为你分配了缺陷 " +
                    newBug.getTitle() +
                    ",请及时处理.";
            messageToNewOwner.setContent(messageContent1);
            messageToNewOwner.setSendId(updater.getId());
            messageToNewOwner.setCreateAt(LocalDateTime.now());
            messageToNewOwner.setCreateBy(operatorId);
            messageToNewOwner.setUpdateAt(LocalDateTime.now());
            messageToNewOwner.setUpdateBy(operatorId);
            messageToNewOwner.setNoticeType(0);
            messageToNewOwner.setType(4);
            Map<String, Object> paramsToNewOwner = new HashMap<>();
            paramsToNewOwner.put("bugId", Optional.ofNullable(newBug.getId()).map(Object::toString).orElse(null));
            paramsToNewOwner.put("proId", Optional.ofNullable(newBug.getProId()).map(Object::toString).orElse(null));
            paramsToNewOwner.put("iterId", Optional.ofNullable(newBug.getIterId()).map(Object::toString).orElse(null));
            paramsToNewOwner.put("milestoneId", Optional.ofNullable(newBug.getMileId()).map(Object::toString).orElse(null));
            paramsToNewOwner.put("reqId", Optional.ofNullable(newBug.getReqId()).map(Object::toString).orElse(null));
            paramsToNewOwner.put("taskId", Optional.ofNullable(newBug.getTaskId()).map(Object::toString).orElse(null));
            paramsToNewOwner.put("payloadType", "bug");
            paramsToNewOwner.put("title", newBug.getTitle());
            messageToOldOwner.setParams(paramsToNewOwner);
            messageToNewOwner.setStatus(1);
            messageToNewOwner.setDeleted(0);
            messageService.sendMessage(messageToNewOwner, List.of(newOwner.getId()));
        }
    }

    @Override
    public Page<BugDynamicVo> pageDynamics(PageBugDynamicRequest pageBugDynamicRequest) {
        //1. 参数校验
        Integer bugId = pageBugDynamicRequest.getBugId();
        ThrowUtils.throwIf(null == bugId, ErrorCode.PARAMS_ERROR);
        pageBugDynamicRequest.standardizeSize();
        Integer current = pageBugDynamicRequest.getCurrent();
        Integer pageSize = pageBugDynamicRequest.getPageSize();
        Page<BugDynamics> page = new Page<>(current, pageSize);
        LambdaQueryWrapper<BugDynamics> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(BugDynamics::getBugId, bugId)
                .orderByDesc(BugDynamics::getCreateAt)
                .orderByDesc(BugDynamics::getId);
        Page<BugDynamics> taskDynamicsPage = bugDynamicsService.page(page, queryWrapper);
        List<BugDynamics> records = taskDynamicsPage.getRecords();
        //2.获取用户数据
        if (records.isEmpty()) {
            return new Page<>();
        }
        List<Integer> userIdList = records.stream()
                .flatMap(bugDynamics -> Stream.of(bugDynamics.getCreateBy()))
                .filter(Objects::nonNull)
                .distinct()
                .collect(Collectors.toList());
        List<UserVO> userVOList = userService.listUserVoByIds(userIdList);
        Map<Integer, UserVO> userVOMap = userVOList.stream().collect(Collectors.toMap(UserVO::getId, userVO -> userVO));
        List<BugDynamicVo> resultList = new ArrayList<>();
        for (BugDynamics bugDynamics : records) {
            BugDynamicVo bugDynamicVo = BeanUtil.copyProperties(bugDynamics, BugDynamicVo.class);
            bugDynamicVo.setCreator(userVOMap.get(bugDynamics.getCreateBy()));
            resultList.add(bugDynamicVo);
        }
        Page<BugDynamicVo> taskDynamicVoPage = new Page<>(current, pageSize);
        BeanUtil.copyProperties(taskDynamicsPage, taskDynamicVoPage);
        taskDynamicVoPage.setRecords(resultList);
        return taskDynamicVoPage;
    }

    @Override
    public BugVo getDetail(Integer id) {
        //1. 参数校验
        ThrowUtils.throwIf(null == id, ErrorCode.PARAMS_ERROR);
        Bug bug = bugMapper.selectById(id);
        //2.获取用户数据
        if (Objects.isNull(bug)) {
            return null;
        }
        BugVo bugVo = BeanUtil.copyProperties(bug, BugVo.class);
        UserVO creator = userService.getUserVoById(bug.getCreateBy());
        UserVO owner = userService.getUserVoById(bug.getOwnerId());
        UserVO updater = userService.getUserVoById(bug.getUpdateBy());
        bugVo.setCreator(creator);
        bugVo.setOwner(owner);
        bugVo.setUpdater(updater);
//        3.获取关联项目、里程碑、迭代、需求、任务名字
        if (bugVo.getProId() != null) {
            Project project = projectService.getById(bugVo.getProId());
            bugVo.setProjectTitle(project.getTitle());
        }
        if (bugVo.getMileId() != null) {
            Milestone milestone = milestoneService.getById(bugVo.getMileId());
            bugVo.setMilestoneTitle(milestone.getTitle());
        }
        if (bugVo.getIterId() != null) {
            Iteration iteration = iterationService.getById(bugVo.getIterId());
            bugVo.setIterationTitle(iteration.getTitle());
        }
        if (bugVo.getReqId() != null) {
            Requirements requirements = requirementsService.getById(bugVo.getReqId());
            bugVo.setRequirementTitle(requirements.getTitle());
        }
        if (bugVo.getTaskId() != null) {
            Task task = taskService.getById(bugVo.getTaskId());
            bugVo.setTaskTitle(task.getTitle());
        }

        return bugVo;
    }

    @Override
    public List<BugVo> listUndoBugList() {
        int loginId = StpUtil.getLoginIdAsInt();
        LambdaQueryWrapper<Bug> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.ne(Bug::getStatus, 4)
                .eq(Bug::getOwnerId, loginId)
                .orderByAsc(Bug::getEndTime)
                .orderByDesc(Bug::getUpdateAt);
        List<Bug> bugList = bugMapper.selectList(queryWrapper);
        if (bugList.isEmpty()) {
            return Collections.emptyList();
        }
        List<Integer> userIdList = bugList.stream()
                .flatMap(bug -> Stream.of(bug.getOwnerId(), bug.getCreateBy()))
                .filter(Objects::nonNull)
                .distinct()
                .collect(Collectors.toList());
        List<UserVO> userVOList = userService.listUserVoByIds(userIdList);
        Map<Integer, UserVO> userVOMap = userVOList.stream().collect(Collectors.toMap(UserVO::getId, userVO -> userVO));
        return bugList.stream().map(bug -> {
            BugVo bugVo = BeanUtil.copyProperties(bug, BugVo.class);
            bugVo.setOwner(userVOMap.get(bug.getOwnerId()));
            bugVo.setCreator(userVOMap.get(bug.getCreateBy()));
            bugVo.setUpdater(userVOMap.get(bug.getUpdateBy()));
            return bugVo;
        }).collect(Collectors.toList());
    }

    @Override
    public List<BugVo> listByProIdAndOwnerId(Integer projectId) {
        int loginId = StpUtil.getLoginIdAsInt();
        LambdaQueryWrapper<Bug> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Bug::getProId, projectId)
                .eq(Bug::getOwnerId, loginId)
                .orderByAsc(Bug::getEndTime)
                .orderByDesc(Bug::getUpdateAt);
        List<Bug> bugList = bugMapper.selectList(queryWrapper);
        if (bugList.isEmpty()) {
            return Collections.emptyList();
        }
        List<Integer> userIdList = bugList.stream()
                .flatMap(bug -> Stream.of(bug.getOwnerId(), bug.getCreateBy()))
                .filter(Objects::nonNull)
                .distinct()
                .collect(Collectors.toList());
        List<UserVO> userVOList = userService.listUserVoByIds(userIdList);
        Map<Integer, UserVO> userVOMap = userVOList.stream().collect(Collectors.toMap(UserVO::getId, userVO -> userVO));
        return bugList.stream().map(bug -> {
            BugVo bugVo = BeanUtil.copyProperties(bug, BugVo.class);
            bugVo.setOwner(userVOMap.get(bug.getOwnerId()));
            bugVo.setCreator(userVOMap.get(bug.getCreateBy()));
            bugVo.setUpdater(userVOMap.get(bug.getUpdateBy()));
            return bugVo;
        }).collect(Collectors.toList());
    }

    private void generateDynamicContent(Bug oldBug, Bug newBug, List<String> contentList, UserVO updater) {
        String content;

        if (!Objects.equals(oldBug.getOwnerId(), newBug.getOwnerId())) {
            UserVO oldOwner = userService.getUserVoById(oldBug.getOwnerId());
            UserVO newOwner = userService.getUserVoById(newBug.getOwnerId());
            if (oldOwner != null && newOwner != null) {
                content = updater.getName() + "将缺陷 " + newBug.getTitle() + "负责人从 " + oldOwner.getName() + " 切换为 " + newOwner.getName() + '.';
                contentList.add(content);
            }
        }
        Integer oldTaskStatus = oldBug.getStatus();
        Integer newTaskStatus = newBug.getStatus();
        if (!Objects.equals(oldTaskStatus, newTaskStatus)) {
            if (null != newTaskStatus && null != oldTaskStatus) {
                content = updater.getName() + "将缺陷 " + newBug.getTitle() + "状态从" + TaskConstant.getBugStatusName(oldBug.getStatus()) + " 切换为 " + TaskConstant.getBugStatusName(newBug.getStatus()) + '.';
                contentList.add(content);
            }
        }
        Integer oldTaskPriority = oldBug.getPriority();
        Integer newTaskPriority = newBug.getPriority();
        if (!Objects.equals(oldTaskPriority, newTaskPriority)) {
            if (null != newTaskPriority && null != oldTaskPriority) {
                content = updater.getName() + "将缺陷 " + newBug.getTitle() + "优先级从" + PriorityConstant.getPriorityName(oldBug.getPriority()) + " 切换为 " + PriorityConstant.getPriorityName(newBug.getPriority()) + '.';
                contentList.add(content);
            }
        }
        String oldTaskTitle = oldBug.getTitle();
        String newTaskTitle = newBug.getTitle();
        if (!Objects.equals(oldBug.getTitle(), newBug.getTitle())) {
            if (null != newTaskTitle && null != oldTaskTitle) {
                content = updater.getName() + "将缺陷标题从 " + oldBug.getTitle() + " 修改为 " + newBug.getTitle() + '.';
                contentList.add(content);
            }
        }
        if (!Objects.equals(oldBug.getMileId(), newBug.getMileId())) {
            Milestone oldMilestone = milestoneService.getById(oldBug.getMileId());
            Milestone newMilestone = milestoneService.getById(newBug.getMileId());
            if (oldMilestone != null && newMilestone != null) {
                content = updater.getName() + "将缺陷 " + newBug.getTitle() + "从里程碑 " + oldMilestone.getTitle() + " 移动到里程碑 " + newMilestone.getTitle() + '.';
                contentList.add(content);
            }
        }
        if (!Objects.equals(oldBug.getIterId(), newBug.getIterId())) {
            Iteration oldIteration = iterationService.getById(oldBug.getIterId());
            Iteration newIteration = iterationService.getById(newBug.getIterId());
            if (oldIteration != null && newIteration != null) {
                content = updater.getName() + "将缺陷 " + newBug.getTitle() + "从迭代 " + oldIteration.getTitle() + " 移动到迭代 " + newIteration.getTitle() + '.';
                contentList.add(content);
            }
        }
        if (!Objects.equals(oldBug.getReqId(), newBug.getReqId())) {
            Requirements oldRequirement = requirementsService.getById(oldBug.getReqId());
            Requirements newRequirement = requirementsService.getById(newBug.getReqId());
            if (oldRequirement != null && newRequirement != null) {
                content = updater.getName() + "将缺陷 " + newBug.getTitle() + "从需求 " + oldRequirement.getTitle() + " 移动到需求 " + newRequirement.getTitle() + '.';
                contentList.add(content);
            }
        }
        if (!Objects.equals(oldBug.getTaskId(), newBug.getTaskId())) {
            Task oldTask = taskService.getById(oldBug.getTaskId());
            Task newTask = taskService.getById(newBug.getTaskId());
            if (oldTask != null && newTask != null) {
                content = updater.getName() + "将缺陷 " + newBug.getTitle() + "从任务 " + oldTask.getTitle() + " 移动到任务 " + newTask.getTitle() + '.';
                contentList.add(content);
            }
        }
        LocalDateTime oleStartTime = oldBug.getStartTime();
        LocalDateTime newStartTime = newBug.getStartTime();
        if (!Objects.equals(oleStartTime, newStartTime)) {
            //格式化时间
            String oldStartTimeStr = oldBug.getStartTime().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
            String newStartTimeStr = newBug.getStartTime().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
            content = updater.getName() + "将缺陷 " + newBug.getTitle() + " 开始时间从 " + oldStartTimeStr + " 修改为 " + newStartTimeStr + '.';
            contentList.add(content);
        }
        LocalDateTime oleEndTime = oldBug.getEndTime();
        LocalDateTime newEndTime = newBug.getEndTime();
        if (!Objects.equals(oleEndTime, newEndTime)) {
            String oldEndTimeStr = oldBug.getEndTime().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
            String newEndTimeStr = newBug.getEndTime().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
            content = updater.getName() + "将缺陷 " + newBug.getTitle() + " 结束时间从 " + oldEndTimeStr + " 修改为 " + newEndTimeStr + '.';
            contentList.add(content);
        }
        if (!Objects.equals(oldBug.getDescription(), newBug.getDescription())) {
            content = updater.getName() + "修改了缺陷 " + newBug.getTitle() + " 描述.";
            contentList.add(content);
        }
        if (!Objects.equals(oldBug.getRemark(), newBug.getRemark())) {
            content = updater.getName() + "修改了缺陷 " + newBug.getTitle() + " 备注.";
            contentList.add(content);
        }
    }
}




